<template>
  <div class="app-container page-child">
    <el-row>
      <div class="card-wrapper">
        <el-card class="box-card">
          <div slot="header" class="header-container">
            <!-- 左侧标题和NFC工具提示 -->
            <div class="left-section">
              <span><b>设备基本信息</b></span>
              <el-tooltip style="margin-left: 4px;" effect="dark" content="点击弹层读取识别NFC切换设备" placement="right" v-if='startSampling.StartUseFlag === "1"'>
                <a href="#" @click="openNFC"><i class="el-icon-copy-document"></i></a>
              </el-tooltip>
            </div>
            <!-- 右侧状态信息和设置图标 -->
            <div class="right-section">
              <a href="#" @click="openMqtt" style="font-size: 14px;margin-top: 3px;"><i class="el-icon-setting"></i></a>
              <span style="font-size: 14px;">采集状态：{{ formatCfgInfo(sensorConfig.configInfo) }}</span>
              <span style="font-size: 14px;">更新时间：{{ sensorConfig.eventTime ? parseTime(sensorConfig.eventTime) : '未知' }}</span>
            </div>
          </div>
          <el-descriptions title="" :column="4">
            <el-descriptions-item label="设备">
              <el-cascader
                  v-model="selectedEquip"
                  :options="equipOptions"
                  :props="{value:'equipmentCode',label:'equipmentName'}"
                  @change="handleChangeEquip"></el-cascader>
            </el-descriptions-item>
            <el-descriptions-item label="设备编码">
              <span style="margin-top: 10px">
                {{ this.isNullOrEmpty(this.selectedEquip) ? '' : this.selectedEquip[this.selectedEquip.length - 1] }}
              </span>
            </el-descriptions-item>
            <el-descriptions-item label="测点数">
              <span style="margin-top: 10px">{{ this.pointList.length }}</span>
            </el-descriptions-item>
            <el-descriptions-item label="数据处理">
              <div class="item">
                <el-tooltip class="item" effect="dark" content="数据上传至服务器或删除本地数据" placement="top">
                  <a href="#" @click="handleUpload"><i class="el-icon-upload"></i></a>
                </el-tooltip>
              </div>
            </el-descriptions-item>
            <el-descriptions-item label="测点">
              <div class="item">
                <el-select v-model="vibQuery.pointCode" @change="changePoint">
                  <el-option v-for="item in pointList" :key="item.pointCode" :label="item.pointName+'-'+item.deviceCode" :value="item.pointCode"/>
                </el-select>
              </div>
            </el-descriptions-item>
            <el-descriptions-item label="变更绑定">
              <div class="item">
                <el-tooltip class="item" effect="dark" content="变更测点绑定" placement="top" v-if='startSampling.StartUseFlag === "1"'>
                  <a href="#" @click="handleAxial"><i class="el-icon-setting"></i></a>
                </el-tooltip>
              </div>
            </el-descriptions-item>
            <el-descriptions-item label="采集参数">
              <div class="item">
                <el-tooltip class="item" effect="dark" content="配置采集参数" placement="top" v-if='startSampling.StartUseFlag === "1"'>
                  <a href="#" @click="handleEquip30"><i class="el-icon-finished"></i></a>
                </el-tooltip>
              </div>
            </el-descriptions-item>
            <el-descriptions-item label="采集间隔">
              <div class="item">
                <el-tooltip class="item" effect="dark" content="配置采集间隔" placement="top" v-if='startSampling.StartUseFlag === "1"'>
                  <a href="#" @click="handleEquip20"><i class="el-icon-finished"></i></a>
                </el-tooltip>
                <el-button type="primary" @click="handleStartUseFlag" style="margin-left: 50px;">
                  {{ startSampling.StartUseFlag === "1" ? "开始采集" : "停止采集" }}
                </el-button>
              </div>
            </el-descriptions-item>
          </el-descriptions>
        </el-card>
      </div>
    </el-row>
    <el-row>
      <el-card class="box-card">
        <el-tabs v-model="activeName" type="card">
          <el-tab-pane label="报警信息" name="zero">
            <keep-alive>
              <alarm-table v-if="activeName==='zero'" :selectedEquip="selectedEquip" :equipList="equipList" />
            </keep-alive>
          </el-tab-pane>
          <el-tab-pane label="振动谱图" name="first">
            <div class="top-bar">
              <div class="item">
                <el-tooltip class="item" effect="dark" content="重新加载数据" placement="top">
                  <a href="#" @click="getLastDate"><i class="el-icon-refresh"></i></a>
                </el-tooltip>
              </div>
              <div class="item">
                <el-date-picker v-model="vibQuery.date" type="date" value-format="yyyy-MM-dd" placeholder="选择日期" @change="getTimeList">
                </el-date-picker>
              </div>
              <div class="item">
                <el-select v-model="vibQuery.eventTime" placeholder="请选择时间">
                  <el-option v-for="item in eventTimeList" :key="item.value" :label="item.label" :value="item.value"/>
                </el-select>
              </div>
              <div class="item">
                <el-select v-model="vibQuery.signalType">
                  <el-option label="原始信号" value="raw"/>
                  <el-option label="包络信号" value="env"/>
                </el-select>
              </div>
              <div class="item">
                <el-select v-model="vibQuery.physicalType">
                  <el-option label="加速度" value="acc"/>
                  <el-option label="速度" value="vel"/>
                </el-select>
              </div>
              <div class="item">
                <el-select v-model="vibQuery.axial">
                  <el-option v-for="item in axialOptions" :key="item.value" :label="item.label" :value="item.value"/>
                </el-select>
              </div>
            </div>
            <div class="card-wrapper" v-if="activeName==='first'" >
              <keep-alive>
                <wave-chart :vibForm="vibQuery"/>
              </keep-alive>
            </div>
            <div class="card-wrapper" v-if="activeName==='first'">
              <keep-alive>
                <fft-chart :vibForm="vibQuery"/>
              </keep-alive>
            </div>
          </el-tab-pane>
          <el-tab-pane label="时域特征" name="second">
            <keep-alive>
              <time-chart v-if="activeName==='second'" :pointCode="vibQuery.pointCode" :axialOptions="axialOptions"/>
            </keep-alive>
          </el-tab-pane>
          <el-tab-pane label="频域特征" name="third">
            <keep-alive>
              <freq-chart v-if="activeName==='third'" :pointCode="vibQuery.pointCode" :axialOptions="axialOptions"/>
            </keep-alive>
          </el-tab-pane>
          <el-tab-pane label="表面温度" name="fourth">
            <keep-alive>
              <temp-chart v-if="activeName==='fourth'" :pointCode="vibQuery.pointCode"/>
            </keep-alive>
          </el-tab-pane>
          <el-tab-pane label="统计数据" name="fifth">
            <keep-alive>
              <conn-chart v-if="activeName==='fifth'" :pointCode="vibQuery.pointCode"/>
            </keep-alive>
          </el-tab-pane>
        </el-tabs>
      </el-card>
    </el-row>
    <!--设置测点轴向对话框-->
    <el-dialog :title="axial.title" :visible.sync="axial.open" :close-on-click-modal="false" :show-close="false" width="500px" append-to-body>
      <Axial v-if="axial.activePoint != null" :point="axial.activePoint" :selectedEquip="selectedEquip" :equipList="equipList" @cancel="cancelAxial"></Axial>
    </el-dialog>
    <!--数据上传对话框-->
    <el-dialog :title="upload.title" :visible.sync="upload.open" :close-on-click-modal="false" :show-close="false" width="700px" append-to-body>
      <Tree @cancel="cancelUpload" @reload="getLastDate"/>
    </el-dialog>
    <!--设置测点采集参数对话框-->
    <el-dialog :title="config.title" :visible.sync="config.open" :close-on-click-modal="false" :show-close="false" width="700px" append-to-body>
      <Config v-if="config.activePoint != null" :point="config.activePoint" @cancel="cancelConfig"/>
    </el-dialog>
    <!--设备采集参数-->
    <el-dialog :title="equip30.title" :visible.sync="equip30.open" :close-on-click-modal="false" :show-close="false" width="700px" append-to-body>
      <Config30 v-if="equip30.activeEquip != null" :equipmentCode="equip30.activeEquip" @cancel="cancelEquip30"/>
    </el-dialog>
    <!--设备采集间隔-->
    <el-dialog :title="equip20.title" :visible.sync="equip20.open" :close-on-click-modal="false" :show-close="false" width="700px" append-to-body>
      <Config20 v-if="equip20.activeEquip != null" :equipmentCode="equip20.activeEquip" @cancel="cancelEquip20"/>
    </el-dialog>
    <!--MQTT配置下发-->
    <el-dialog :title="mqtt.title" :visible.sync="mqtt.open" :close-on-click-modal="false" :show-close="false" width="700px" append-to-body>
      <el-form ref="mqttForm" :model="mqtt.form" :rules="mqtt.rules" label-width="120px">
        <el-form-item label="传感器编码" prop="deviceCode">
          <el-input v-model="mqtt.form.deviceCode" placeholder="传感器编码"/>
        </el-form-item>
        <el-form-item label="配置信息" prop="config">
          <el-input type="textarea" :rows="5" v-model="mqtt.form.config" placeholder="配置信息"/>
        </el-form-item>
      </el-form>
      <div class="bottom_wrap">
        <el-button type="primary" @click="submitMqtt">下 发</el-button>
        <el-button @click="cancelMqtt">取 消</el-button>
      </div>
    </el-dialog>
    <!--NFC切换-->
    <el-dialog :title="nfc.title" :visible.sync="nfc.open" :close-on-click-modal="false" :show-close="false" width="700px" append-to-body>
      <el-form ref="nfcForm" :model="nfc.form" :rules="nfc.rules" label-width="120px">
        <el-form-item label="NFC编码" prop="nfcCode">
          <el-input ref="nfcInputRef" v-model="nfc.form.nfcCode" placeholder="NFC编码" clearable @change="handleChangeNFC"/>
        </el-form-item>
      </el-form>
      <div class="bottom_wrap">
        <el-button type="primary" @click="submitNFC">切 换</el-button>
        <el-button @click="cancelNFC">取 消</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import {getLastDate, getSensorConfig, getTimeList} from "@/api/raw";
import WaveChart from "@/views/wave/waveChart.vue";
import FftChart from "@/views/wave/fftChart.vue";
import Axial from "@/views/point/index.vue";
import Tree from "@/views/point/tree.vue";
import TempChart from "@/views/temp/tempChart.vue";
import ConnChart from "@/views/conn/connChart.vue";
import {queryEquip, queryPoint, setStartUseFlag, updateDevice} from "@/api/equip";
import Config from "@/views/point/config.vue";
import TimeChart from "@/views/diag/timeChart.vue";
import FreqChart from "@/views/diag/freqChart.vue";
import Config20 from "@/views/equip/config20.vue";
import Config30 from "@/views/equip/config30.vue";
import AlarmTable from "@/views/diag/alarmTable.vue";
import {parseTime} from "@/utils/common";

export default {
  components: { AlarmTable, WaveChart,FftChart,TempChart,ConnChart,Axial,Tree,Config,TimeChart,FreqChart,Config20,Config30},
  data() {
    return {
      sensorConfig: {
        eventTime: "",
        configInfo: ""
      },
      pollingInterval: null,
      activeName: 'first',
      vibQuery: {
        pointCode: null,
        date: '',
        eventTime: '',
        axial: 'x',
        runningStatus: '',
        physicalType: "acc",
        featureType: 'rms',
        signalType: "raw"
      },
      eventTimeList: [],
      selectedEquip: null,
      equipList: [],
      equipOptions: [],
      pointList: [],
      axial: {
        open: false,
        title: '',
        activePoint: null
      },
      upload: {
        open: false,
        title: ''
      },
      defaultAxial: [{
        label: "H",
        value: "x"
      }, {
        label: "A",
        value: "y"
      }, {
        label: "V",
        value: "z"
      }],
      axialOptions:[],
      config: {
        open: false,
        title: '',
        activePoint: null
      },
      equip20: {
        open: false,
        title: '',
        activeEquip: null
      },
      equip30: {
        open: false,
        title: '',
        activeEquip: null
      },
      startSampling: {
        equipmentCode: null,
        StartUseFlag: "1"
      },
      mqtt: {
        open: false,
        title: '',
        form: {
          deviceCode: null,
          config: null
        },
        rules: {
          deviceCode: [
            {required: true, message: '请输入传感器编码', trigger: 'blur'},
          ],
          config: [
            {required: true, message: '请输入配置信息', trigger: 'blur'},
            {
              validator: (rule, value, callback) => {
                if (value) {
                  try {
                    JSON.parse(value);
                    callback();
                  } catch (e) {
                    callback(new Error('配置信息必须是有效的JSON格式'));
                  }
                } else {
                  callback();
                }
              },
              trigger: 'blur'
            }
          ]
        }
      },
      nfc: {
        open: false,
        title: '',
        form: {
          nfcCode: null
        },
        rules: {
          nfcCode: [
            {required: true, message: '请输入NFC编码', trigger: 'blur'},
          ],
        }
      }
    }
  },
  created() {
    this.buildEquipTree();
    let local = localStorage.getItem("samplingTask");
    if (local) this.startSampling = JSON.parse(local);

    // this.pointList = [{
    //   pointCode: '84f703e0c972',
    //   pointName: '84f703e0c972'
    // }, {
    //   pointCode: '84f703e0c91c',
    //   pointName: '84f703e0c91c'
    // }]
    // this.vibQuery.pointCode = this.pointList[0].pointCode
    // this.changePoint()
  },
  methods: {
    parseTime,
    buildEquipTree() {
      this.equipOptions = [];
      queryEquip().then(res => {
        this.equipList = res.data;
        this.equipOptions = this.handleTree(res.data, "equipmentId");
        this.setDefaultSelected();
      });
    },
    setDefaultSelected(targetId) {
      // 查找第一个 level === 30 的节点路径
      const findPath = (nodes, level = []) => {
        for (const node of nodes) {
          const currentPath = [...level, node.equipmentCode];
          // 如果提供了 targetId，则查找匹配的设备
          if (targetId != null) {
            if (node.equipmentCode === targetId) {
              return currentPath;
            }
          } else {
            if (node.level === 30) {
              return currentPath; // 找到符合条件的值路径
            }
          }
          if (node.children) {
            const childPath = findPath(node.children, currentPath);
            if (childPath) return childPath; // 如果子节点中找到，返回路径
          }
        }
        return null; // 没有匹配项
      };
      const defaultPath = findPath(this.equipOptions);
      if (defaultPath) {
        this.selectedEquip = defaultPath; // 设置默认值路径
        this.queryPoint();
      }
    },
    handleChangeEquip(value) {
      this.queryPoint();
    },
    // 统一重置查询状态
    resetQueryState() {
      this.vibQuery.date = null;
      this.vibQuery.eventTime = null;
      this.eventTimeList = [];
      this.sensorConfig = {
        eventTime: "",
        configInfo: ""
      };
      // 清掉之前定时器
      if (this.pollingInterval) {
        clearInterval(this.pollingInterval);
        this.pollingInterval = null;
      }
    },
    queryPoint() {
      this.pointList = [];
      this.vibQuery.pointCode = null;
      this.vibQuery.eventTime = null;
      this.eventTimeList = [];
      if (this.isNullOrEmpty(this.selectedEquip)) return;
      let query = {
        equipmentCode: this.selectedEquip[this.selectedEquip.length - 1]
      }
      queryPoint(query).then(res => {
        this.pointList = res.data;
        if (this.isNullOrEmpty(this.pointList)) return;
        let point = this.pointList[0];
        this.vibQuery.pointCode = point.pointCode;
        this.bindAxial(point.axial);
        this.changePoint();
      })
    },
    changePoint() {
      this.getLastDate();
      // 启动轮询
      this.refreshCfgInfo();
    },
    getLastDate() {
      this.vibQuery.date = null;
      this.vibQuery.eventTime = null;
      this.eventTimeList = [];
      if (!this.vibQuery.pointCode) return;
      getLastDate(this.vibQuery.pointCode).then(res => {
        if (res.data) {
          this.vibQuery.date = this.parseTime(res.data, '{y}-{m}-{d}');
          this.getTimeList();
        }
      })
    },
    getTimeList() {
      this.eventTimeList = [];
      this.vibQuery.eventTime = null;
      if(!this.vibQuery.pointCode) return;
      let query = {
        pointCode: this.vibQuery.pointCode,
        date: this.vibQuery.date
      };
      getTimeList(query).then(res => {
        if (res.data) {
          let eventTime = null;
          res.data.forEach(item => {
            let obj = {
              value: item,
              label: this.parseTime(item, '{h}:{i}:{s}')
            };
            this.eventTimeList.push(obj);
            eventTime = obj.value;
          })
          this.vibQuery.eventTime = eventTime;
        }
      })
    },
    bindAxial(axialStr) {
      if (this.isNullOrEmpty(axialStr)) {
        this.axialOptions = this.defaultAxial;
        return;
      }
      this.axialOptions = [];
      let axial = JSON.parse(axialStr);
      for (let key in axial) {
        if (axial[key] !== '无效') {
          let obj = {
            value: key,
            label: axial[key]
          };
          this.axialOptions.push(obj);
        }
      }
      // 如果当前选择轴向已设置无效，则重新设置下查询的轴向
      if (!this.axialOptions.some(p => p.value === this.vibQuery.axial)) {
        this.vibQuery.axial = this.axialOptions[0].value;
      }
    },
    handleAxial() {
      if(!this.vibQuery.pointCode) return;
      let point = this.pointList.find(l => l.pointCode === this.vibQuery.pointCode);
      this.axial.open = true;
      this.axial.activePoint = point;
      this.axial.title = '测点配置- ' + point.pointName;
    },
    cancelAxial(point) {
      if (point) {
        // 查找IoT绑定的测点
        if (point.deviceCode) {
          const index = this.pointList.findIndex(l => l.deviceCode === point.deviceCode);
          if (index !== -1) {
            const find = {...this.pointList[index]}; // 创建副本，避免直接修改原对象
            find.deviceCode = ""; // 清空deviceCode，避免显示在多个测点中
            this.$set(this.pointList, index, find);
          }
        }
        // 替换point对象
        const index = this.pointList.findIndex(p => p.pointCode === point.pointCode);
        if (index !== -1) {
          this.$set(this.pointList, index, point); // 响应式的更新数组
        }
        // 重新加载轴向
        this.bindAxial(point.axial);

        // 启动轮询
        this.refreshCfgInfo();
      }
      this.axial.open = false;
    },
    handleUpload() {
      this.upload.open = true;
      this.upload.title = '数据上传或删除';
    },
    cancelUpload() {
      this.upload.open = false;
    },
    handleConfig() {
      if(!this.vibQuery.pointCode) return;
      let point = this.pointList.find(l => l.pointCode === this.vibQuery.pointCode);
      this.config.open = true;
      this.config.activePoint = point;
      this.config.title = "采集参数";
    },
    cancelConfig() {
      this.config.open = false;
    },
    // 工作机组
    handleEquip20() {
      if (this.isNullOrEmpty(this.selectedEquip)) return;
      let equipmentCode = this.selectedEquip[this.selectedEquip.length - 2];
      this.equip20.open = true;
      this.equip20.activeEquip = equipmentCode;
      this.equip20.title = "采集间隔";
    },
    cancelEquip20() {
      this.equip20.open = false;
    },
    // 设备级设备
    handleEquip30() {
      if (this.isNullOrEmpty(this.selectedEquip)) return;
      let equipmentCode = this.selectedEquip[this.selectedEquip.length - 1];
      this.equip30.open = true;
      this.equip30.activeEquip = equipmentCode;
      this.equip30.title = "采集参数";
    },
    cancelEquip30() {
      this.equip30.open = false;
    },
    // 设置采集标识
    handleStartUseFlag() {
      if (this.isNullOrEmpty(this.selectedEquip)) return;
      let equipmentCode = this.selectedEquip[this.selectedEquip.length - 2];
      if (this.startSampling.StartUseFlag === "1") {
        this.startSampling.equipmentCode = equipmentCode
        this.startSampling.StartUseFlag = "2";
        localStorage.setItem("samplingTask", JSON.stringify(this.startSampling));
      } else {
        this.startSampling.StartUseFlag = "1";
        localStorage.removeItem("samplingTask");
      }
      setStartUseFlag(this.startSampling).then(res => {
        if (res.code === 200) {
          this.$modal.msgSuccess("操作成功");
        }
      })
    },
    refreshCfgInfo() {
      // 清掉之前定时器
      if (this.pollingInterval) {
        clearInterval(this.pollingInterval);
        this.pollingInterval = null;
      }

      this.sensorConfig = {
        eventTime: "",
        configInfo: ""
      }
      if (!this.vibQuery.pointCode) return;

      let find = this.pointList.find(l => l.pointCode === this.vibQuery.pointCode);
      if (!find || !find.deviceCode) return;

      // 封装获取数据的逻辑
      const fetchConfig = async () => {
        try {
          const res = await getSensorConfig(find.deviceCode);
          this.sensorConfig = res.data;
        } catch (error) {
          console.error("获取传感器配置失败:", error);
        }
      }

      // 立即执行一次
      fetchConfig();

      // 然后设置定时器，10秒后再次执行
      this.pollingInterval = setInterval(fetchConfig, 10000);
    },
    // 解析 CfgInfo 并格式化 SUFg
    formatCfgInfo(configStr) {
      if (!configStr) return "未知";

      const config = {};
      configStr.split(',').forEach(item => {
        const [key, value] = item.split(':');
        config[key] = value;
      });

      // 处理 SUFg 状态
      const startUseFlag = {
        '0': '工厂模式',
        '1': '等待中',
        '2': '采集中'
      };
      return config.SUFg ? startUseFlag[config.SUFg] || config.SUFg : "未知";
    },
    openMqtt() {
      this.mqtt.open = true;
      this.mqtt.title = "MQTT配置";
      if (this.vibQuery.pointCode) {
        let find = this.pointList.find(l => l.pointCode === this.vibQuery.pointCode);
        if (find && find.deviceCode) this.mqtt.form.deviceCode = find.deviceCode;
      }
      this.mqtt.form.config = '{\n' +
          '  "Otaflag":1,\n' +
          '  "Otaurl":"http://10.42.0.1/Mingserve_WifiSensor2.3.2c.bin"\n' +
          '}';
    },
    submitMqtt() {
      this.$refs["mqttForm"].validate(valid => {
        if (valid) {
          // let config = JSON.parse(this.mqtt.form.config);
          // config.SensorID = this.mqtt.form.deviceCode;
          // this.mqtt.form.config = JSON.stringify(config);
          updateDevice(this.mqtt.form).then(res => {
            if (res.code === 200) {
              this.$modal.msgSuccess("下发成功");
              this.cancelMqtt();
            }
          });
        }
      })
    },
    cancelMqtt() {
      this.mqtt.open = false;
    },
    openNFC() {
      this.nfc.open = true;
      this.nfc.title = "NFC识别";
      this.nfc.form.nfcCode = "";
      this.$nextTick(() => {
        this.$refs.nfcInputRef.$el.querySelector('input').focus();
      });
    },
    handleChangeNFC() {
      if (this.nfc.form.nfcCode.length === 10) {
        this.submitNFC();
      }
    },
    submitNFC() {
      this.$refs["nfcForm"].validate(valid => {
        if (valid) {
          let find = this.equipList.find(l => l.nfcCode === this.nfc.form.nfcCode);
          if (find) {
            this.setDefaultSelected(find.equipmentCode);
            this.$modal.msgSuccess("已成功切换为：" + find.equipmentName);
            this.nfc.open = false;
          } else {
            this.$modal.msgError("该编码未找到对应设备");
            this.nfc.form.nfcCode = "";
          }
        }
      })
    },
    cancelNFC() {
      this.nfc.open = false;
    }
  }
}
</script>
<style lang="scss" scoped>
.card-wrapper {
  background: #fff;
  margin-bottom: 16px;
}

.top-bar {
  margin-bottom: 20px !important;
  display: flex;
}
.top-bar > .item {
  margin: 0 0 0 10px;
}

.top-bar > .item .el-select {
  width: 200px;
}

.top-bar .el-date-editor {
  width: 200px;
}
::v-deep(.el-descriptions-item__label) {
  margin-top: 10px;
}
.item a {
  display: inline-block; padding: 10px; border-radius: 5px;
}
.bottom_wrap {
  margin-top: 10px;
  text-align: right;
}

.header-container {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 0;
}

.left-section {
  display: flex;
  align-items: center;
  gap: 8px; /* 标题和NFC图标之间的间距 */
}

.right-section {
  display: flex;
  align-items: center;
  gap: 16px; /* 右侧元素之间的间距 */
}
</style>
